package runtime;

//TEst  
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression;
import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedScanList;
import com.google.gson.Gson;

import data.dynamodbfunctions.Persistence_Helper_Feature;
import data.dynamodbfunctions.Persistence_Helper_FeatureAssociation;
import data.exceptions.Dynamo_DB_Functions_Exception;
import data.features.Feature;
import data.features.FeatureAssociation;
import data.meta.Meta_Method;
import data.meta.Meta_Property;
import data.meta.Metadata;
import data.objects.PubForum;
import data.objects.Select_Condition;

public class Test_Features {
	static List<Feature> featureList = null;
	static List<FeatureAssociation> associationList = null;
	/**
	 * @param args
	 * @throws Dynamo_DB_Functions_Exception 
	 */
	public static void features() throws Dynamo_DB_Functions_Exception{
		Gson gson = new Gson();
		//Create Feature
		System.out.println("Create Features");

		Feature testfeature=new Feature("0","FeatureA","10","TestType", "TestBeschreibung");
		Persistence_Helper_Feature.getInstance().create(testfeature);
		
		Feature testfeature2=new Feature("0","FeatureB","15","TestType", "TestBeschreibung");
		Persistence_Helper_Feature.getInstance().create(testfeature2);

		//Read Features
//		System.out.println("Read Features");
//
//		featureList = Persistence_Helper_Feature.getInstance().readAllwithHashKey("0");
//		for(Feature a: featureList){
//			System.out.println("Feature");
//			System.out.println(gson.toJson(a));
//		}
		
		//Update Feature
//		System.out.println("Update two Features");
//
//		featureList = Persistence_Helper_Feature.getInstance().readAllwithHashKey("0");
//		Feature testfeatureUpdate;
//		for(Feature a: featureList){
//			if (a.getName().equals("FeatureA")){
//				a.setName("A");
//				testfeatureUpdate = a;
//				Persistence_Helper_Feature.getInstance().update(testfeatureUpdate);
//			}
//			if (a.getName().equals("FeatureB")){
//				a.setName("B");
//				testfeatureUpdate = a;
//				Persistence_Helper_Feature.getInstance().update(testfeatureUpdate);
//			}
//
//		}		
		
		//Delete Features
//		System.out.println("Delete Features");
//		for(Feature a: featureList){
//			Persistence_Helper_Feature.getInstance().delete(a.getTenantID(), a.getFeatureID());
//		}
	}
	
	public static void featureAssociations() throws Dynamo_DB_Functions_Exception{
		Gson gson = new Gson();
		featureList = Persistence_Helper_Feature.getInstance().readAllwithHashKey("0");
		String sourceID = null;
		String targetID = null;
		
//		//Create FeatureAssociaton
//		System.out.println("Create a FeatureAssociaton");
//
//		//This only works for two Features in the Table!
//		Iterator<Feature> i = featureList.iterator();
//		while (i.hasNext()){
//			sourceID=i.next().getFeatureID();
//			targetID=i.next().getFeatureID();;
//		}
//		System.out.println("SourceID = "+sourceID + ", TargetID = "+targetID);
//		FeatureAssociation testfeatureAssociation=new FeatureAssociation("0","TestType",sourceID,targetID);
//		Persistence_Helper_FeatureAssociation.getInstance().create(testfeatureAssociation);
//
//		//Read FeatureAssociations
//		System.out.println("Read FeatureAssociations");
//
//
//		associationList = Persistence_Helper_FeatureAssociation.getInstance().readAllwithHashKey("0");
//		for(FeatureAssociation a: associationList){
//			System.out.println("FeatureAssociation");
//			System.out.println(gson.toJson(a));
//		}
		
		//Update FeatureAssociation
		System.out.println("Update a FeatureAssociation");

		associationList = Persistence_Helper_FeatureAssociation.getInstance().readAllwithHashKey("0");
		FeatureAssociation testfeatureAssociationUpdate;
		for(FeatureAssociation a: associationList){

			a.setType("new Type");
			testfeatureAssociationUpdate = a;
			Persistence_Helper_FeatureAssociation.getInstance().update(testfeatureAssociationUpdate);
		}

		
		
		//Delete FeatureAssociations
//		System.out.println("Delete FeatureAssociatons");
//		for(FeatureAssociation a: associationList){
//			Persistence_Helper_FeatureAssociation.getInstance().delete(a.getTenantID(), a.getFeatureAssociationID());
//		}
	}
	public static void clearTable(){
		AmazonDynamoDBClient dynamoDB = new AmazonDynamoDBClient(new ClasspathPropertiesFileCredentialsProvider());
        Region euWest1 = Region.getRegion(Regions.EU_WEST_1);
        dynamoDB.setRegion(euWest1);        
        DynamoDBMapper mapper = new DynamoDBMapper(dynamoDB);
        
        DynamoDBScanExpression scanExpression1 = new DynamoDBScanExpression();
		PaginatedScanList<Feature> all = mapper.scan(Feature.class, scanExpression1);
		for(Feature a:all){
			mapper.delete(a);
		}
		DynamoDBScanExpression scanExpression2 = new DynamoDBScanExpression();
		PaginatedScanList<FeatureAssociation> all2 = mapper.scan(FeatureAssociation.class, scanExpression2);
		for(FeatureAssociation a:all2){
			mapper.delete(a);
		}
	}
	public static void testFeatureAssociations() throws Dynamo_DB_Functions_Exception{

		//Read SubFeatures
		Gson gson = new Gson();
		System.out.println("Read Feature Tree");
		System.out.println("");
		
		List<Select_Condition> conditionlist=new ArrayList<Select_Condition>();
		conditionlist.add(new Select_Condition("Description","=","Wurzel"));
		Feature wurzel=Persistence_Helper_Feature.getInstance().readwithAttributes("0", conditionlist).get(0);
		System.out.println(wurzel.getName());
		
		List<Feature> subfeature=wurzel.toSubFeatures();
		for(Feature f:subfeature){
			Feature feature=Persistence_Helper_Feature.getInstance().read("0", f.getFeatureID());
			System.out.println("------>"+feature.getName());
			List<Feature> subfeature2=feature.toSubFeatures();
			for(Feature f2:subfeature2){
				Feature feature2=Persistence_Helper_Feature.getInstance().read("0", f2.getFeatureID());
				System.out.println("------> ------>"+feature2.getName());
			}
		}
		
		
		
//		featureList = Persistence_Helper_Feature.getInstance().readAllwithHashKey("0");
//		List<String> subFeatures = new ArrayList<String>();
//		for(Feature a: featureList){
//			subFeatures = a.toSubFeatures();
//			System.out.println("Subfeatures to Feature " + a.getName() + ": "+subFeatures);
//						
//		}
//		
//		//Read ParentFeatures
//		System.out.println("Read ParentFeatures");
//
//		featureList = Persistence_Helper_Feature.getInstance().readAllwithHashKey("0");
//		String parentFeature = null;
//		for(Feature a: featureList){
//			parentFeature = a.toParentFeature();
//			System.out.println("Parentfeature to Feature " + a.getName() + ": "+parentFeature);
//		}
	}
		
	
	public static void creatFeatureBaum() throws Dynamo_DB_Functions_Exception{
		Feature wurzel=new Feature("0","Forum-APP","0","TestType", "Wurzel");
		Persistence_Helper_Feature.getInstance().create(wurzel);
		
		List<Feature> knotenlist=new ArrayList<Feature>();
		Feature forumoperations=new Feature("0","Forum Operations","0","TestType", "Knote");
		Feature threadoperations=new Feature("0","Thread Operations","0","TestType", "Knote");
		Feature entryoperations=new Feature("0","Entry Operations","0","TestType", "Knote");
		Feature usermanagement=new Feature("0","User Management","0","TestType", "Knote");
						
		knotenlist.add(forumoperations);
		knotenlist.add(threadoperations);
		knotenlist.add(entryoperations);
		knotenlist.add(usermanagement);
		for(Feature a:knotenlist){
			Persistence_Helper_Feature.getInstance().create(a);
			FeatureAssociation association=new FeatureAssociation("0","Mandatory",wurzel.getFeatureID(),a.getFeatureID());
			Persistence_Helper_FeatureAssociation.getInstance().create(association);
		}
		
		List<Feature> featurelistforum=new ArrayList<Feature>();
		featurelistforum.add(new Feature("0","Create","0","TestType", "Blatt"));
		featurelistforum.add(new Feature("0","Edit","0","TestType", "Blatt"));
		for(Feature a:featurelistforum){
			Persistence_Helper_Feature.getInstance().create(a);
			FeatureAssociation association=new FeatureAssociation("0","Mandatory",forumoperations.getFeatureID(),a.getFeatureID());
			Persistence_Helper_FeatureAssociation.getInstance().create(association);
		}
		
		List<Feature> featurelistthread=new ArrayList<Feature>();
		featurelistthread.add(new Feature("0","Create","0","TestType", "Blatt"));
		featurelistthread.add(new Feature("0","Edit","0","TestType", "Blatt"));
		featurelistthread.add(new Feature("0","Subscribe","0","TestType", "Blatt"));
		featurelistthread.add(new Feature("0","Search","0","TestType", "Blatt"));
		for(Feature a:featurelistthread){
			Persistence_Helper_Feature.getInstance().create(a);
			FeatureAssociation association=new FeatureAssociation("0","Mandatory",threadoperations.getFeatureID(),a.getFeatureID());
			Persistence_Helper_FeatureAssociation.getInstance().create(association);
		}
		
		List<Feature> featurelistoperations=new ArrayList<Feature>();
		featurelistoperations.add(new Feature("0","Create","0","TestType", "Blatt"));
		featurelistoperations.add(new Feature("0","Edit","0","TestType", "Blatt"));
		featurelistoperations.add(new Feature("0","Search","0","TestType", "Blatt"));
		featurelistoperations.add(new Feature("0","Quote","0","TestType", "Blatt"));
		featurelistoperations.add(new Feature("0","Already read","0","TestType", "Blatt"));
		for(Feature a:featurelistoperations){
			Persistence_Helper_Feature.getInstance().create(a);
			FeatureAssociation association=new FeatureAssociation("0","Mandatory",entryoperations.getFeatureID(),a.getFeatureID());
			Persistence_Helper_FeatureAssociation.getInstance().create(association);
		}
		
		List<Feature> featurelistuser=new ArrayList<Feature>();
		featurelistuser.add(new Feature("0","Admin","0","TestType", "Blatt"));
		featurelistuser.add(new Feature("0","Moderator","0","TestType", "Blatt"));
		featurelistuser.add(new Feature("0","User","0","TestType", "Blatt"));
		for(Feature a:featurelistuser){
			Persistence_Helper_Feature.getInstance().create(a);
			FeatureAssociation association=new FeatureAssociation("0","Mandatory",usermanagement.getFeatureID(),a.getFeatureID());
			Persistence_Helper_FeatureAssociation.getInstance().create(association);
		}
	}
	
	public static void reassembleFeatures () throws Dynamo_DB_Functions_Exception{
		Gson gson = new Gson();
//		featureList = Persistence_Helper_Feature.getInstance().readAllwithHashKey("0");
		featureList = Feature.readAll("0");
		List<Feature> subFeatureList = null;
		List<Feature> subSubFeatureList = null;
		Feature root;
		//get Subfeatures to root
		for(Feature a: featureList){
//			root = a.toParentFeature();
//			System.out.println("Root = "+root);
			if (a.name.equals("Forum-APP")){
				root = a;
				subFeatureList = a.toSubFeatures();
				System.out.println("Root = "+gson.toJson(a));
				System.out.println("Subfeatures = "+subFeatureList);
			}
		}
		//get Subfeatures to Forum Operations
		for (Feature b: subFeatureList){
			if (b.name.equals("Forum Operations")){
				subSubFeatureList = b.toSubFeatures();
				System.out.println("Subsubfeatures = "+subSubFeatureList);
			}
		}
		//Look up the Metadata to Create
		List <Meta_Property> metaProperties = null;
		List <Meta_Method> metaMethods = null;
		for (Feature c: subSubFeatureList){
			if (c.name.equals("Create")){
				System.out.println("\nFeature: "+c.name);
				metaProperties = c.getMetadata().getProperties();
				metaMethods = c.getMetadata().getMethods();
			}
		}
		System.out.println("");
		//Properties Editable?
		for (int i = 0; i<metaProperties.size(); i++){
			System.out.println("Meta-Property: "+metaProperties.get(i).getName()+", editable = "+metaProperties.get(i).getEditable());
		}
		System.out.println("");
		//Methods Enabled?
		for (int i = 0; i<metaMethods.size(); i++){
			System.out.println("Meta-Method: "+metaMethods.get(i).getName()+", enabled = "+metaMethods.get(i).getEnabled());
			if (metaMethods.get(i).getName().equals("update")){
				System.out.println("Update is enabled: "+metaMethods.get(i).getEnabled());
			}
		}
	}
	
	public static void reassembleFeaturesShort () throws Dynamo_DB_Functions_Exception{
		featureList = Feature.readAll("0");
		Feature root = null;
		Feature searchedFeature;
		//get Subfeatures to root
		for(Feature a: featureList){
			if (a.toParentFeature()==null){
				root = a;
				System.out.println("Root = "+root);
			}
		}
		
		searchedFeature = recursiveSearch ("Subscribe", root);
		System.out.println("Searched Feature = "+searchedFeature);
		
		List <Meta_Method> metaMethods = searchedFeature.getMetadata().getMethods();
		for (int i = 0; i<metaMethods.size(); i++){
			if (metaMethods.get(i).getName().equals("update")){
				System.out.println("Update is enabled: "+metaMethods.get(i).getEnabled());
			}
		}
	}
	
	public static Feature recursiveSearch(String gi,Feature node){
	        if (node.getName().equals(gi))
	            return node;
	        List<Feature> children = node.toSubFeatures(); 
	        Feature temp;
	        if (children.size()>0)
	        for (int i = 0; i < children.size(); i++) {         
	            temp = recursiveSearch(gi, children.get(i));
	            if(temp!=null)
	                return temp;
	        }
	        return null;
	 
	}
	
	public static void main(String[] args) {

		try {
//			features();
//			featureAssociations();
//			testFeatureAssociations();
//			clearTable();
//			creatFeatureBaum();
//			testFeatureAssociations();
//			reassembleFeatures ();
			reassembleFeaturesShort ();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
